import java.net._
import java.io._
import java.util.Calendar
import java.text.SimpleDateFormat
import java.util.Date
import scala.collection.JavaConversions._
import util._
import util.HttpClient.toUrl
import scala.io._
import java.nio.charset._
import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.Futures.future
import scala.actors.Future
import javax.swing.JOptionPane

object Aamulehti {
  val acroreader = "\"C:\\Program Files (x86)\\Adobe\\Reader 9.0\\Reader\\AcroRd32.exe\""
  val loginPageUrl = "http://www2.aamulehti.fi/login.shtml?http://www2.aamulehti.fi/verkkolehti/r/paper.cgi"
  val loginServiceUrl = "http://login.almamedia.fi/poke.pl"
  val downloadFileFolder = new File("c:\\temp\\" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()))

  def tempPdfFile(i: Int) = new File(downloadFileFolder, "page" + i + ".pdf")
  def pdfUrl(urlBase: String, i: Int) = urlBase + "/" + tempPdfFile(i).getName()
  def pdfFolderUrl(osa: String) = "http://www2.aamulehti.fi/verkkolehti/a/" + osa + new SimpleDateFormat("yyyy/MM/dd").format(new Date())
  def resultFile(name: String) = new File(downloadFileFolder, name)


  def saveAsynchronously(ub: String, si: Int = 1): List[File] = {
    val loaderDialog = Dialogs.loadingDialog

    val dialogActor = actor {
      loop {
        react {
          case pageNumber: Int => loaderDialog.message(pageNumber)
        }
      }
    }
    
    val allPages = future {
      def saveAllPdfPages(urlBase: String, i: Int = 1): List[File] = {
        dialogActor ! i
        if (HttpClient.getAndSave(pdfUrl(urlBase, i), tempPdfFile(i)))
          tempPdfFile(i) :: saveAllPdfPages(urlBase, i + 1)
        else
          Nil
      }
      try{
        Thread.`yield`()
        saveAllPdfPages(ub, si)
      }finally{
        loaderDialog.dispose()
      }
    }
    loaderDialog.show()

    if(loaderDialog.userCanceledOperation){
      System.exit(1)
    }
    
    return allPages()
  }

  def login(user: String, password: String): Option[URL] = {
    val postData = Map(
      "url" -> "http://www2.aamulehti.fi/verkkolehti/r/paper.cgi",
      "retrypage" -> "http://www2.aamulehti.fi/loginretry.shtml",
      "checkin" -> "/nph-checkin.cgi",
      "registrpage" -> "alma-avain",
      "user" -> user,
      "pass" -> password,
      "Submit32" -> "OK")
    return LehdenUrlParser.parseUrlFromHtml(HttpClient.post(loginServiceUrl, postData))
  }

  def openInAcrobatReader(file: File) {
    try {
      Runtime.getRuntime.exec(acroreader + " " + file.getAbsolutePath())
    } catch {
      case e: Exception => {
        Dialogs.acroreadNotFound(file)
      }
    }
  }

  def loadAndDisplay(urlPart: String, pdf: String) {
    PdfConcatenator.concatenate(saveAsynchronously(pdfFolderUrl(urlPart)), resultFile(pdf))
    println(resultFile(pdf).getAbsolutePath())
    openInAcrobatReader(resultFile(pdf))
  }

  def loadAamulehti(username: String, password: String) {
    CookieHandler.setDefault(new CookieManager())
    HttpURLConnection.setFollowRedirects(true)
    downloadFileFolder.mkdirs()

    HttpClient.getAndForget(loginPageUrl)
    login(username, password) match {
      case Some(frontPageUrl) => {
        HttpClient.getAndForget(frontPageUrl)

        loadAndDisplay("", "aamulehti.pdf")
        Calendar.getInstance().get(Calendar.DAY_OF_WEEK) match {
          case Calendar.SUNDAY => loadAndDisplay("sunnuntai/", "sunnuntai.pdf")
          case Calendar.FRIDAY => loadAndDisplay("valo/", "valo.pdf")
          case Calendar.THURSDAY => loadAndDisplay("moro/", "moro.pdf")
          case _ => {}
        }
      }
      case None => println("Login failed for user: " + username)
    }
  }

  def main(args: Array[String]) {
    try{
      Dialogs.askUsernameAndPassword() match {
        case Some((username, password)) => loadAamulehti(username, password)
        case None => Unit
      }
    }finally{
      System.exit(0)
    }
  }
}
